package com.xgr.wonderful.utils;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import com.google.gson.Gson;
import com.xgr.wonderful.constant.Constant;
import com.xgr.wonderful.entity.Status;
import com.xgr.wonderful.utils.HttpProxy.IHttpRequestListener;

import android.content.Context;

/**
 * 全局的本地点赞关系
 * @author lsj
 *
 */
public class LocalLikeRelationsUtils {
	
	private static final String TAG ="LocalLikeRelationsUtils" ;
	/*持有私有静态实例，防止被引用，此处赋值为null，目的是实现延迟加载 */
	private static LocalLikeRelationsUtils singletonLikeRelationUtils = null;
	
	private Set<Integer> likeRelations;
	/* 私有构造方法，防止被实例化 */ 
	private LocalLikeRelationsUtils() {

	}
	
	/**
	 * 可能 是低效率的同步 方法
	 * synchronized关键字锁住的是这个对象，这样的用法，在性能上会有所下降，
	 * 因为每次调用getInstance()，都要对对象上锁，事实上，只有在第一次创建
	 * 对象的时候需要加锁，之后就不需要了，可改为getInstance2
	 * @return
	 */
	public static synchronized LocalLikeRelationsUtils getInstance1() {
		if (singletonLikeRelationUtils == null) {
			singletonLikeRelationUtils = new LocalLikeRelationsUtils();
		}
		return singletonLikeRelationUtils;
	}
	/**
	 * 似乎解决了之前提到的问题，将synchronized关键字加在了内部，也就是说当
	 * 调用的时候是不需要加锁的，只有在instance为null，并创建对象的时候才需
	 * 要加锁，性能有一定的提升.这样的情况，还是有可能有问题的，看下面的情况：
	 * Java指令中创建对象和赋值操作是分开进行的，也就是说instance = new Singleton();
	 * 语句是分两步执行的。但是JVM并不保证这两个操作的先后顺序，也就是说有可能JVM会为新的Singleton
	 * 实例分配空间，然后直接赋值给instance成员，然后再去初始化这个Singleton实例。这样就可能出错了
	 * @return
	 */
	public static LocalLikeRelationsUtils getInstance2(){
		if (singletonLikeRelationUtils == null){
			synchronized (singletonLikeRelationUtils) {
				if (singletonLikeRelationUtils == null){
					singletonLikeRelationUtils = new LocalLikeRelationsUtils() ;
				}
			}
		}
		return singletonLikeRelationUtils ;
	}
	
	/**
	 * 因为我们只需要在创建类的时候进行同步，
	 * 所以只要将创建和getInstance()分开，单独为创建加synchronized关键字
	 * 比上面 的1 ,2更好的方法，和上面 和syncInit配合使用
	 * @return
	 */
	public static LocalLikeRelationsUtils getInstance (){
		if (singletonLikeRelationUtils == null){
			syncInit() ;
		}
		return singletonLikeRelationUtils ;
	}
	/**
	 * 是private 
	 */
	private static synchronized void syncInit (){
		if (singletonLikeRelationUtils == null){
			singletonLikeRelationUtils = new LocalLikeRelationsUtils() ;
		}
	}

	/**
	 * 此过程在SplashActivity/ WelcomeActivity中调用 
	 * 构建 本地用户点赞关系 ,必须在LocalUserUtils初始化后才可使用,因为里面会用到user信息.
	 * 每次启动时可以本地加载（如果已经有信息了） /从服务器加载(本地无)like信息，
	 *  HashSet 类：按hash算法存储集合中的元素，具有很好的存取和存取性能
	 *  得到likerelations后保存一次
	 */
	public void buildLikeRelations(final Context context) {
		if (likeRelations != null) {
			LogUtils.i(TAG, "likerelations not null and return") ;
			return;
		}
		likeRelations = Cache.getUserLikeRelations();//先加载 本地的
		if (likeRelations!= null){
			LogUtils.i(TAG, "local like relations=:"+new Gson().toJson(likeRelations)) ;
		}
		LogUtils.i(TAG, "local like relations=null?"+String.valueOf(likeRelations == null)) ;
		if (likeRelations == null) { //说明 本地没有数据 ,调试
			String statusJson = null;
			Status status = new Status(LocalUserUtils.getInstance().getLocalUserID());
			if (status.getUserid() == null) {
				LogUtils.i(TAG, "need to have local user info") ;
			}
			try {
				statusJson = new Gson().toJson(status);
			} catch (Exception e) {
				// TODO: handle exception
				e.printStackTrace();
			}
			if (statusJson != null) {
				HttpProxy httpProxy = new HttpProxy();
				
				httpProxy.getLikeRelations(statusJson , new IHttpRequestListener() {

					@Override
					public void OnHttpRequestSuccessful(String result,
							int errCode) {
						LogUtils.i(TAG, "pull relations from server:"+ result) ;
						Integer[] likeStatus = null;
						if (errCode == Constant.ERR_HTTP_REQUEST_SUCCESS) {
							LogUtils.i(TAG, "request ok") ;
							try {
								likeStatus = new Gson().fromJson(result,
										Integer[].class);
							} catch (Exception e) {
								// TODO: handle exception
								e.printStackTrace();
							}
							if (likeStatus != null) {
								likeRelations = new HashSet<Integer>(Arrays
										.asList(likeStatus));
								saveLikeRelations() ;//保存到本场
							}else {
								
							}
						} else {
							ToastFactory.getToast(context, "获取点赞关系失败") ;
							LogUtils.i(TAG, "get like relations failure info: "+ result);
						}
					}

					@Override
					public void OnHttpRequestStart() {
					}

					@Override
					public void OnHttpRequestFailure(String info) {
						// TODO Auto-generated method stub
						ToastFactory.getToast(context, "获取点赞关系失败，请检查网络环境后重试").show();
					}
				});
			}
		}
	}
	
	public boolean isLiked(Integer statusID) {
		if (likeRelations != null) {
			return likeRelations.contains(statusID);
		}
		likeRelations = new HashSet<Integer>();
		return false;
	}
	
	public void addLikeRelations(Integer statusID) {
		if (likeRelations == null) {
			likeRelations = new HashSet<Integer>();
		}
		LogUtils.i(TAG, "add like statusid:"+ statusID);
		likeRelations.add(statusID);
		LogUtils.i(TAG, "after add:"+new Gson().toJson(likeRelations));
	}
	
	public void saveLikeRelations() {
		String likeRelationsJson = new Gson().toJson(likeRelations);
		Cache.putUserLikeRelations(likeRelationsJson);
		LogUtils.i(TAG, "save like relations to local:"+likeRelationsJson );
	}
}
